package com.agileai.bpm.controller.define;

import java.util.ArrayList;
import java.util.List;

import org.codehaus.jettison.json.JSONObject;

import com.agileai.bpm.bizmoduler.define.WfProcessManage;
import com.agileai.bpm.model.DataFieldsDocument.DataFields;
import com.agileai.bpm.model.ProcessDefineDocument;
import com.agileai.bpm.model.ProcessDefineDocument.ProcessDefine;
import com.agileai.bpm.model.VariableType;
import com.agileai.bpm.model.VariableType.DataType;
import com.agileai.domain.DataParam;
import com.agileai.domain.DataRow;
import com.agileai.hotweb.domain.FormSelect;
import com.agileai.hotweb.domain.FormSelectFactory;
import com.agileai.hotweb.domain.core.User;
import com.agileai.hotweb.renders.AjaxRenderer;
import com.agileai.hotweb.renders.LocalRenderer;
import com.agileai.hotweb.renders.ViewRenderer;
import com.agileai.util.DateUtil;
import com.agileai.util.StringUtil;

public class WfProcessGeneralEditHandler extends WfProcessInfoHandler{
	public WfProcessGeneralEditHandler(){
		super();
		this.serviceId = "defineService";
	}
	
	@SuppressWarnings("rawtypes")
	public ViewRenderer prepareDisplay(DataParam param){
		DataRow record = getService().getRecord(param);
		this.setAttributes(record);

		ProcessDefine processDefine = null;
		ProcessDefineDocument processDefineDocument = (ProcessDefineDocument)this.getSessionAttribute(WfProcessDefineEditHandler.ProcessDefineSessionKey);
		if (processDefineDocument != null){
			ProcessDefine tempProcessDefine = processDefineDocument.getProcessDefine();
			if (tempProcessDefine.getId().equals(record.getString("WFP_ID"))){
				processDefine = tempProcessDefine;
			}else{
				String processDefineXML = record.getString("WFP_DEFINE");
				processDefine = regetProcessDefine(processDefineXML);
			}
		}else{
			String processDefineXML = record.getString("WFP_DEFINE");
			processDefine = regetProcessDefine(processDefineXML);
		}
		
		DataFields dataFields = processDefine.getDataFields();
		List processVars = new ArrayList();
		if (dataFields != null){
			processVars = buildProcessVars(dataFields);
		}
		setAttribute("processVars", processVars);
		setAttribute("WFP_CODE", processDefine.getCode());
		setAttribute("WFP_NAME", processDefine.getName());
		setAttribute("WFP_DESC", processDefine.getDescription());
		initDataTypeFormSelectAttribute();
		
		this.setAttribute("currentTabIndex", getAttribute("currentTabIndex", "0"));
		
		processPageAttributes(param);
		return new LocalRenderer(getPage());
	}
	
	public ViewRenderer doSaveAction(DataParam param){
		String responseText = FAIL;
		try {
			String code = param.get("WFP_CODE");
			String name = param.get("WFP_NAME");
			String desc = param.get("WFP_DESC");
			ProcessDefine processDefine = getProcessDefine();
			processDefine.setCode(code);
			processDefine.setName(name);
			processDefine.setDescription(desc);
			
			processProcessVariables(processDefine, param);
			
			User user = (User)getUser();
			DataRow record = getService().getRecord(param);
			DataParam newParam = record.toDataParam(true);
			newParam.update(param);
			newParam.put("WFP_MODIFY_TIME", DateUtil.getDateByType(DateUtil.YYMMDDHHMI_HORIZONTAL));
			newParam.put("WFP_MODIFIER", user.getUserId());
			
			String processJson = param.get("processJson");
			if (!StringUtil.isNullOrEmpty(processJson)){
				JSONObject jsonObject = new JSONObject(processJson);
				newParam.put("WFP_GRAPH", jsonObject.toString());
			}
			ProcessDefineDocument processDefineDocument = (ProcessDefineDocument)this.getSessionAttribute(WfProcessDefineEditHandler.ProcessDefineSessionKey);
			if (processDefineDocument != null){
				newParam.put("WFP_DEFINE", processDefineDocument.toString());					
			}			
			getService().updateRecord(newParam);	
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
		}
		responseText = SUCCESS;
		return new AjaxRenderer(responseText);
	}
	
	private void processProcessVariables(ProcessDefine processDefine,DataParam param){
		if (processDefine.getDataFields() != null){
			for (int i=0;i < processDefine.getDataFields().sizeOfDataFieldArray();i++){
				int varIndex = i;
				VariableType variableType = processDefine.getDataFields().getDataFieldArray(i);
				String varCode = param.get("VAR_CODE_"+i);
				variableType.setCode(varCode);
				variableType.setDescription(param.get("VAR_DESC_"+varIndex));
				DataType dataType = DataType.Factory.newInstance();
				dataType.setStringValue(param.get("VAR_TYPE_"+varIndex));
				
				variableType.xsetDataType(dataType);
				variableType.setInitialValue(param.get("VAR_INIT_VALUE_"+varIndex));
			}
		}
	}
	
	protected void processPageAttributes(DataParam param) {
		FormSelect typeGroupFormSelect = FormSelectFactory.create("WF_GROUP");
		String wfGroup = getAttributeValue("WFP_GROUP");
		if (StringUtil.isNullOrEmpty(wfGroup)){
			wfGroup = param.get("WFP_GROUP");
		}
		typeGroupFormSelect.setSelectedValue(wfGroup);
		this.setAttribute("WFP_GROUP", typeGroupFormSelect);
		FormSelect stateSelect = FormSelectFactory.create("WF_STATE");
		String wfState = getAttributeValue("WFP_STATE");
		if (StringUtil.isNullOrEmpty(wfState)){
			wfState = "unrelease";
		}
		stateSelect.setSelectedValue(wfState);
		this.setAttribute("WFP_STATE", stateSelect);
	}	
	
	public ViewRenderer doAddProcessVariableAction(DataParam param){
		ProcessDefine processDefine = getProcessDefine();
		DataFields dataFields = processDefine.getDataFields();
		if (dataFields == null)
				dataFields = processDefine.addNewDataFields();
		dataFields.addNewDataField();
		this.setAttribute("currentTabIndex", "1");
		return prepareDisplay(param);
	}
	
	public ViewRenderer doDelProcessVariableAction(DataParam param){
		ProcessDefine processDefine = getProcessDefine();
		
		processProcessVariables(processDefine, param);
		
		int varIndex = param.getInt("varIndex");
		processDefine.getDataFields().removeDataField(varIndex);
		this.setAttribute("currentTabIndex", "1");
		return prepareDisplay(param);
	}
	
	private WfProcessManage getService() {
		return (WfProcessManage)this.lookupService(WfProcessManage.class);
	}
	
	private ProcessDefine regetProcessDefine(String processDefine){
		try {
			ProcessDefineDocument processDefineDocument = ProcessDefineDocument.Factory.parse(processDefine);
			this.getSessionAttributes().put(WfProcessDefineEditHandler.ProcessDefineSessionKey, processDefineDocument);
			return processDefineDocument.getProcessDefine();
		} catch (Exception e) {
			log.error(e.getLocalizedMessage(), e);
			return null;
		}
	}	
	
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private List buildProcessVars(DataFields dataFields){
		List result = new ArrayList();
		VariableType[] variableTypes = dataFields.getDataFieldArray();
		if (variableTypes != null){
			for (int i=0; i< variableTypes.length;i++){
				VariableType variableType = variableTypes[i];
				DataRow row = new DataRow();
				row.put("VAR_CODE",variableType.getCode());
				row.put("VAR_DESC",variableType.getDescription());
				row.put("VAR_TYPE",variableType.getDataType());
				row.put("VAR_INIT_VALUE",variableType.getInitialValue());
				result.add(row);
			}
		}
		return result;
	}
	
	private void initDataTypeFormSelectAttribute(){
		FormSelect varTypeSelect = new FormSelect();
		varTypeSelect.setHasBlankValue(false);
		varTypeSelect.addValue("string", "字符");
		varTypeSelect.addValue("number", "数值");
		setAttribute("VAR_TYPE", varTypeSelect);
		
		FormSelect isVarSelect = new FormSelect();
		isVarSelect.setHasBlankValue(false);
		isVarSelect.addValue("true", "是");
		isVarSelect.addValue("false","否");
		setAttribute("IS_VAR", isVarSelect);
	}
}
